package com.ufcg.lvc.client.prototipacao;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FileUpload;
import com.google.gwt.user.client.ui.FormPanel;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent;
import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.smartgwt.client.types.ListGridEditEvent;
import com.smartgwt.client.widgets.grid.CellFormatter;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.ufcg.lvc.client.GreetingService;
import com.ufcg.lvc.client.GreetingServiceAsync;
import com.ufcg.lvc.client.GreetingServiceCRUD;
import com.ufcg.lvc.client.GreetingServiceCRUDAsync;
import com.ufcg.lvc.client.UserData;
import com.ufcg.lvc.shared.FieldVerifier;

public class CarregarImagem {

	AbsolutePanel panelCarregarImg;
	private TextBox novoAluno2;
	String nomeTurma_, disciplina_, instituicao_, ano_, tituloProva_;
	Image image;
	List<String> valores,corretas;
	ArrayList<String> listaEncontradas = new ArrayList<String>();
	int numeroQuestoes;
	private Button btnVoltar, btnRecalcular, btnSalvar;
	private ListGrid listGrid;
	final TextBox totalTB;
	String nomeAlunoDaProva = "";
	private FieldVerifier verificador =  new FieldVerifier();
	UserData UD;
	
	public static GreetingServiceCRUDAsync getServicoCRUD() {
		return GWT.create(GreetingServiceCRUD.class);
	}

	public static GreetingServiceAsync getServico() {
		return GWT.create(GreetingService.class);
	}

	public CarregarImagem(String nomeTurma, String disciplina, String instituicao,
			String ano, String prova, UserData uD) 
	{
		UD = uD;
		nomeTurma_ = nomeTurma;
		disciplina_ = disciplina;
		instituicao_ = instituicao;
		ano_ = ano;
		tituloProva_ = prova;
		
		listGrid = new ListGrid();
		listGrid.setShowAllRecords(true);
		listGrid = new ListGrid();
		listGrid.setSize("626px", "164px");
		listGrid.setCanSort(false);
		listGrid.setCanMultiSort(false);
		
		panelCarregarImg = new AbsolutePanel();
		panelCarregarImg.setSize("900px", "707px");
		
		getServicoCRUD().getAlunoDaProva(tituloProva_, nomeTurma, UD.getId_usuario(), new AsyncCallback<String>() {
			@Override
			public void onSuccess(String result) {
				nomeAlunoDaProva = result;
				TextBox novoAluno2 = new TextBox();
				novoAluno2.setSize("570px", "14px");
				novoAluno2.setText(result);
				novoAluno2.setEnabled(false);
				panelCarregarImg.add(novoAluno2, 108, 418);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				TextBox novoAluno2 = new TextBox();
				novoAluno2.setSize("570px", "14px");
				novoAluno2.setText("");
				novoAluno2.setEnabled(true);
				panelCarregarImg.add(novoAluno2, 108, 418);
			}
		});
  
        ListGridField field0 = new ListGridField("numero", "Questão", 100);  
        field0.setCanEdit(false);
        
        ListGridField field1 = new ListGridField("esperada", "Resposta esperada", 150);  
        field1.setCanEdit(false);  
  
        ListGridField field2 = new ListGridField("encontrada", "Resposta encontrada", 150);  
        field2.setValueMap("A", "B", "C", "D", "E","-");
        ListGridField field3 = new ListGridField("valor", "Valor da questão", 150);  
        field3.setCanEdit(false);
        		        
        ListGridField field4 = new ListGridField("ganho", "Valor ganho", 150);
        
        field4.setCellFormatter(new CellFormatter() {  
            public String format(Object value, ListGridRecord record, int rowNum, int colNum) {  
                if(value == null) return null;  
                NumberFormat nf = NumberFormat.getFormat("#,##00.00");  
                try {  
                    return nf.format(((Number) value).longValue());  
                } catch (Exception e) {  
                    return value.toString();  
                }  
        }});  

        listGrid.setFields(field0, field1, field2, field3, field4);          
        listGrid.setCanEdit(true);  
        listGrid.setEditEvent(ListGridEditEvent.CLICK);  
        listGrid.setEditByCell(true);  
        		
		getRespostasEValoresGabarito();
		
		
		
		panelCarregarImg.add(listGrid, 60, 460);
		
		Label lblAluno = new Label("Aluno:");
		panelCarregarImg.add(lblAluno, 60, 424);
		
		Label titulo = new Label("Enviar gabaritos");
		titulo.setStyleName("gwt-TituloMedio");
		panelCarregarImg.add(titulo, 0, 10);

		btnVoltar = new Button("Voltar");
		btnVoltar.setSize("91px", "29px");
		panelCarregarImg.add(btnVoltar, 437, 678);

		btnSalvar = new Button("Salvar");
		btnSalvar.setEnabled(false);
		btnSalvar.setSize("91px", "29px");
		panelCarregarImg.add(btnSalvar, 340, 678);
		
		image = new Image();
		panelCarregarImg.add(image, 60, 69);
		image.setSize("626px", "343px");

		final Button btnAdicionarGabarito = new Button("Adicionar gabarito");
		btnAdicionarGabarito.setEnabled(true);
		panelCarregarImg.add(btnAdicionarGabarito, 692, 101);
		
		btnVoltar.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				panelCarregarImg.clear();
				final ExibirTurma n = new ExibirTurma(nomeTurma_, disciplina_,instituicao_, ano_,UD);
				panelCarregarImg.add(n.getPanel());
		}});
				
		AbsolutePanel absolutePanel = new AbsolutePanel();
		panelCarregarImg.add(absolutePanel, 692, 67);
		absolutePanel.setSize("208px", "28px");

		final FormPanel formPanel = new FormPanel();
		panelCarregarImg.add(formPanel, 692, 69);
		formPanel.setSize("208px", "28px");
		formPanel.setEncoding(FormPanel.ENCODING_MULTIPART);
		formPanel.setMethod(FormPanel.METHOD_POST);
		formPanel.setAction(GWT.getModuleBaseURL() + "uploadServlet");

		FileUpload preFileUpload = new FileUpload();
		formPanel.setWidget(preFileUpload);
		preFileUpload.setSize("208px", "24px");
		preFileUpload.setName("fileUpload");		
		
		totalTB = new TextBox();
		totalTB.setEnabled(false);
		totalTB.setText("0.0");
		panelCarregarImg.add(totalTB, 560, 629);
		totalTB.setSize("40px", "16px");
		
		Label lblTotal = new Label("Total:");
		panelCarregarImg.add(lblTotal, 518, 633);
		
		btnRecalcular = new Button("Recalcular");
		btnRecalcular.setEnabled(false);
		panelCarregarImg.add(btnRecalcular, 614, 629);
		btnRecalcular.setSize("72px", "29px");
				
		
		formPanel.addSubmitCompleteHandler(new SubmitCompleteHandler() {
			@Override
			public void onSubmitComplete(SubmitCompleteEvent event) {
				Window.alert("Corrigindo prova...");
				image.setUrl(event.getResults().substring(97, 122));
				getServico().corrigirProvas(event.getResults().substring(97, 117),event.getResults().substring(119, 122),new AsyncCallback<String>() {
				//  59, 117 ou 97, 117
				//	image.setUrl(event.getResults().substring(118, 143));
				//	getServico().corrigirProvas(event.getResults().substring(118, 138),event.getResults().substring(140, 143),new AsyncCallback<String>() {
				@Override
				public void onSuccess(String result) {
					getListaEncontradas(result.split("---"));
					setDataEncontradas();
					doComparacao();
					btnSalvar.setEnabled(true);
				}

				@Override
				public void onFailure(Throwable caught) {
					System.out.println("Deu erro "	+ caught.getMessage());
				}
			});
				

			}
		});

		btnAdicionarGabarito.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				formPanel.submit();		
				if (corretas != null){corretas.clear();}
				if (valores != null){valores.clear();}
			}
		});
		
		btnRecalcular.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				somarPontos();
			}
		});
		
		btnSalvar.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				try {
//					String nomeAluno = novoAluno.getText();
					if (nomeAlunoDaProva.equals("")){
						nomeAlunoDaProva = novoAluno2.getText();	
					}
					getServicoCRUD().getIDAluno(nomeAlunoDaProva, UD.getId_usuario(), new AsyncCallback<String>() {
							@Override
							public void onSuccess(String result) {
								getServicoCRUD().salvarNotaDaProva(tituloProva_, totalTB.getText(), new AsyncCallback<Boolean>() {
									@Override
									public void onSuccess(Boolean result) {
										Window.alert("Nota do aluno salva.");
										panelCarregarImg.clear();
										final ExibirTurma n = new ExibirTurma(nomeTurma_, disciplina_,instituicao_, ano_, UD);
										panelCarregarImg.add(n.getPanel());
									}
									
									@Override
									public void onFailure(Throwable caught) {
										Window.alert("Ocorreu um erro servidor. Tente novamente recarregar a página.");
									}
								});
							}
							@Override
							public void onFailure(Throwable caught) {
								Window.alert("Aluno não encontrado. Digite um nome válido.");
							}
						});	
				} catch (Exception e) {
					Window.alert("Ocorreu um erro servidor. Tente novamente recarregar a página.");
				}
			}
		});
    }  
		  
	private void somarPontos(){
		double total = 0;
		for (int i = 0; i < numeroQuestoes; i++) {
			String valor = listGrid.getRecord(i).getAttribute("ganho");
			if (verificador.isDouble(valor)  && Double.parseDouble(valor.replace(",", ".")) >=0){
				Double p = Double.parseDouble(valor.replace(",", "."));
				total += p;
			} else {
				Window.alert("O valor \""+ valor + "\" não é válido.");
			}
		}	
		totalTB.setText(total + "");
	}
    private ListGridRecord[] getDataInicial() {
    	ListGridRecord[] qRecord = new ListGridRecord[numeroQuestoes];
    	for (int i = 0; i < numeroQuestoes; i++) {
			if (corretas.get(i).equals("#")){
				corretas.set(i, "-");
			}
		}
		for (int i = 0; i < numeroQuestoes; i++) {
			qRecord[i] = new NameValueRecord((i+1)+"", corretas.get(i), "",Double.parseDouble(valores.get(i)), 0);
		}
		return qRecord;
    }  
    
    private void setDataEncontradas() {
		for (int i = 0; i < numeroQuestoes; i++) {
			listGrid.getRecord(i).setAttribute("encontrada", listaEncontradas.get(i));			
		}
    }  
    
    private void doComparacao() {
		for (int i = 0; i < numeroQuestoes; i++) {
			if (listGrid.getRecord(i).getAttribute("encontrada").equals(listGrid.getRecord(i).getAttribute("esperada"))) {
				listGrid.getRecord(i).setAttribute("ganho", listGrid.getRecord(i).getAttribute("valor"));	
			} else {
				listGrid.getRecord(i).setAttribute("ganho", 0.0);
			}			
		}
		btnRecalcular.setEnabled(true);
		somarPontos();
		Window.alert("1 - Confiras se respostas extraídas do gabarito correspondem com as respostas esperadas. Caso você encontre algum erro, poderá alterar 'Resposta encontrada' e 'Valor ganho' de cada questão" +
				 "\n\n2 - Para alterar 'Resposta encontrada' e 'Valor ganho' de uma questão, basta clicar duas vezes sobre o campo desejado e digitar o valor correto." +
				 "\n\n3 - Caso tenha feito alguma alteração em 'Valor ganho', clique no botão 'Recalcular' para atualizar a nota da prova." +
				 "\n\n4 - Clique no botão 'Salvar' para armazenar a nota do aluno.");
		listGrid.redraw();
    }  
  
    public static class NameValueRecord extends ListGridRecord {  
    	String encontrada, esperada;
    	double valorMaximo, valorQuestao;   
        public NameValueRecord(String numero1, String esperada1, String encontrada1, double valorMaximo1, double valorQuestao1) {
    		setNumero(numero1);
    		setEncontrada(encontrada1);
    		setEsperada(esperada1);
    		setValorMaximo(valorMaximo1);
    		setValorQuestao(valorQuestao1);
        }
        	  
		public String getEncontrada() {return getAttribute("encontrada");}
		public String getEsperada() {return getAttribute("esperada");}
		public double getValorMaximo() {return getAttributeAsDouble("valor");}
		public double getValorQuestao() {return getAttributeAsDouble("ganho");}
		public String getNumero() {return getAttribute("numero");}				
		public void setNumero(String numero) {setAttribute("numero", numero);}
		public void setEsperada(String esperada) {setAttribute("esperada", esperada);}
		public void setEncontrada(String encontrada) {setAttribute("encontrada", encontrada);}
		public void setValorMaximo(double valorMaximo) {setAttribute("valor", valorMaximo);}
		public void setValorQuestao(double valorQuestao) {setAttribute("ganho", valorQuestao);}  
    }  

	public AbsolutePanel getPanel() {
		return panelCarregarImg;
	}
	
	public void getRespostasEValoresGabarito() {
		getServicoCRUD().getRespostasEValoresGabarito(tituloProva_, nomeTurma_, UD.getId_usuario(), new AsyncCallback<ArrayList<ArrayList<String>>>() {
			
			@Override
			public void onSuccess(ArrayList<ArrayList<String>> result) {
				numeroQuestoes = result.get(0).size();
				corretas = result.get(0);
				valores  = result.get(1);
				listGrid.setData(getDataInicial());
				listGrid.redraw();
			}
		
			
			@Override
			public void onFailure(Throwable caught) {
				System.out.println("Erro ao recuperar respostas e valores");
			}
		});
	}
	
	private void getListaEncontradas(String[] r) {
		
		listaEncontradas.add((r[2].charAt(2) + ""));		listaEncontradas.add((r[4].charAt(2) + ""));
		listaEncontradas.add((r[6].charAt(2) + ""));		listaEncontradas.add((r[8].charAt(2) + ""));
		listaEncontradas.add((r[10].charAt(2) + ""));		listaEncontradas.add((r[12].charAt(2) + ""));
		listaEncontradas.add((r[14].charAt(2) + ""));		listaEncontradas.add((r[16].charAt(2) + ""));
		listaEncontradas.add((r[18].charAt(2) + ""));		listaEncontradas.add((r[20].charAt(2) + ""));	
		
		if (numeroQuestoes > 10) {
			listaEncontradas.add((r[22].charAt(2) + ""));			listaEncontradas.add((r[24].charAt(2) + ""));
			listaEncontradas.add((r[26].charAt(2) + ""));			listaEncontradas.add((r[28].charAt(2) + ""));
			listaEncontradas.add((r[30].charAt(2) + ""));			listaEncontradas.add((r[32].charAt(2) + ""));
			listaEncontradas.add((r[3].charAt(2) + "")); 			listaEncontradas.add((r[5].charAt(2) + ""));
			listaEncontradas.add((r[7].charAt(2) + "")); 			listaEncontradas.add((r[9].charAt(2) + ""));		
		
			if (numeroQuestoes > 20) {
				listaEncontradas.add((r[11].charAt(2) + ""));				listaEncontradas.add((r[13].charAt(2) + ""));
				listaEncontradas.add((r[15].charAt(2) + ""));				listaEncontradas.add((r[17].charAt(2) + ""));
				listaEncontradas.add((r[19].charAt(2) + ""));				listaEncontradas.add((r[21].charAt(2) + ""));
				listaEncontradas.add((r[23].charAt(2) + ""));				listaEncontradas.add((r[25].charAt(2) + ""));
				listaEncontradas.add((r[27].charAt(2) + ""));				listaEncontradas.add((r[29].charAt(2) + ""));
				listaEncontradas.add((r[31].charAt(2) + ""));				listaEncontradas.add((r[33].charAt(2) + ""));
			}
		}
		for (int i = 0; i < numeroQuestoes; i++) {
			if (listaEncontradas.get(i).equals("#")) {listaEncontradas.set(i, "-");}
		}
	}
}
